#include <hash_map>
#include <vector>
#include <string>
using namespace std;

#define WORKSPACE "D:\\LIANG\\Desktop\\MT_Workspace\\"
#define CNIN "D:\\LIANG\\Desktop\\MT_Workspace\\cn.txt"
#define JPIN "D:\\LIANG\\Desktop\\MT_Workspace\\jp.txt"

#define MAX_CN_LEN 30
#define MAX_JP_LEN 30
#define MIN_PHRASE_APPEARENCE 3
#define MAX_RATIO 3

typedef basic_string<int> phrase;
//typedef basic_string<int> phrasePair;
//typedef pair<int,double> pointnode;
//typedef pair<int, int> phrasePair;
typedef unsigned long long int phrasePair;
typedef phrase sent;

//phrasePair createPrasePair(const phrase& cn, const phrase& jp){
//	basic_string<int> lengthIndicator;
//	lengthIndicator.push_back(cn.length());
//	return basic_string<int>(lengthIndicator + cn +jp);
//}
//phrase extractCN(const phrasePair& pp){
//	return pp.substr(1,pp.at(0));
//}
//phrase extractJP(const phrasePair& pp){
//	return pp.substr(1+pp.at(0));
//}

template<class keyType, class valueType>
class my_hash_map : public std::hash_map<keyType, valueType>
{
public:
	void set(const keyType& key, const valueType& value){
		hash_map<keyType, valueType>::iterator i = this->find(key);
		if (i == end()){
			insert ( std::pair<keyType, valueType>(key, value) );
		}else{
			i->second = value;
		}
	}
	bool contains(const keyType& key){
		return find(key) != end();
	}
	void doAddCount(const keyType& key){
		hash_map<keyType, valueType>::iterator i = this->find(key);
		if (i == end()){
			insert ( std::pair<keyType, valueType>(key, 1) );
		}else{
			i->second += 1;
		}
	}
};

class point_map : public my_hash_map<phrase, pair<int, double>>
{

public:
	void set(const phrase& ph, const int phid, const double& point){
		hash_map<phrase, pair<int, double>>::iterator it = this->find(ph);
		if (it == end()){
			insert ( std::pair<phrase, pair<int,double>>(ph, pair<int,double>(phid, point)) );
		}else{
			it->second = pair<int,double>(phid, point);
		}
	}
	double getID(const phrase& ph){
		hash_map<phrase, pair<int, double>>::iterator it = this->find(ph);
		if (it == end()){
			return -1;
		}else{
			return (it->second).first;
		}
	}
	void addPoint(const phrase& ph, const double& point){
		hash_map<phrase, pair<int, double>>::iterator it = this->find(ph);
		if (it != end()){
			it->second = pair<int,double>((it->second).first, (it->second).second+point);
		}
	}
	void doAddPoint(const phrase& ph, const double& point){
		hash_map<phrase, pair<int, double>>::iterator it = this->find(ph);
		if (it != end()){
			it->second = pair<int,double>((it->second).first, (it->second).second+point);
		}else{
			insert(pair<phrase, pair<int, double>>(ph, pair<int, double>(size(), point)));
		}
	}
	double getPoint(const phrase& ph){
		hash_map<phrase, pair<int, double>>::iterator it = this->find(ph);
		if (it == end()){
			return 0;
		}else{
			return (it->second).second;
		}
	}
};

class pair_point_map : public my_hash_map<phrasePair, double>
{

public:
	void doAddPoint(const phrasePair& ph, const double& point){
		hash_map<phrasePair, double>::iterator it = this->find(ph);
		if (it != end()){
			it->second += point;
		}else{
			insert(pair<phrasePair,double>(ph, point));
		}
	}
	void addPoint(const phrasePair& ph, const double& point){
		hash_map<phrasePair, double>::iterator it = this->find(ph);
		if (it != end()){
			it->second += point;
		}
	}
	double getPoint(const phrasePair& ph){
		hash_map<phrasePair, double>::iterator it = this->find(ph);
		if (it == end()){
			return 0;
		}else{
			return it->second;
		}
		return 0;
	}
};



my_hash_map<string, int> jpword2idMap;
vector<string> jpid2wordMap;
my_hash_map<string, int> cnword2idMap;
vector<string> cnid2wordMap;
extern vector<const sent> cnCorpus;
extern vector<const sent> jpCorpus;


string jpsent2str(const sent& sen){
	string r = jpid2wordMap[sen[0]];
	for (int i=1;i<sen.size();i++){
		r += " " + jpid2wordMap[sen[i]];
	}
	return r;
}
string cnsent2str(const sent& sen){
	string r = cnid2wordMap[sen[0]];
	for (int i=1;i<sen.size();i++){
		r += " " + cnid2wordMap[sen[i]];
	}
	return r;
}
string jpid2word(int i){
	return jpid2wordMap[i];
}
string cnid2word(int i){
	return cnid2wordMap[i];
}
int jpword2id(string word){
	hash_map<string, int>::const_iterator tmpIter = jpword2idMap.find(word);
	if (tmpIter != jpword2idMap.end())
		return tmpIter->second;
	else return -1;
}
int jpaddNewWord(string word){
	int tmpID = jpid2wordMap.size();
	jpword2idMap[word] = tmpID;
	jpid2wordMap.push_back(word);
	return tmpID;
}
int cnword2id(string word){
	hash_map<string, int>::const_iterator tmpIter = cnword2idMap.find(word);
	if (tmpIter != cnword2idMap.end())
		return tmpIter->second;
	else return -1;
}
int cnaddNewWord(string word){
	int tmpID = cnid2wordMap.size();
	cnword2idMap[word] = tmpID;
	cnid2wordMap.push_back(word);
	return tmpID;
}
